import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

class TetrisBlock extends JPanel implements KeyListener{
	/**
	 * 
	 */
	public static final long serialVersionUID = 1L;
	//全局变量
	public int TetrisType;	//方块类型	
	public int RotateState;	//方块状态
	public int x;
	public int y;
	public int i = 0;
	public int j = 0;
	public int flag = 0;	//已经放下的方块
	public int score = 0; //初始化分数
	
	int [][] map = new int[13][23];	//定义地图范围
		//七种方块的形状
	public int form[][][] = new int[][][] {
		{ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
		  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
		  { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
		  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 } },
		
		{ { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		  { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
		  { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		  { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } },
		
		{ { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		  { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
		  { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
		  { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } },
		
        { { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
          { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
          { 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
          { 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
        
        { { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
          { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
          { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
          { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },

        { { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
          { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
          { 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
          { 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
        
        { { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
          { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
          { 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
          { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }
	};
	
	public TetrisBlock() {
		//初始化
		newTetris();
		initMap();
		wall();
		Timer timer = new Timer(1000, new TimerListener());	//初始化定时器
		timer.start();	//定时器开始
	}
	
	public void newTetris() {
		//生成新方块
		TetrisType=(int) (Math.random() * 1000)% 7;	//七种方块类型
		RotateState=(int) (Math.random() * 1000)% 4;	//四种方块状态
		x = 4;	//新方块出现的位置
		y = 0;
		if(gameover(x, y) == 1) {	//游戏结束
			initMap();
			wall();
			score = 0;
				//弹出三个选项
			int select = 
				JOptionPane.showConfirmDialog(this, "游戏结束，还来吗");
			//OK就重新生成新方块
			if(select == JOptionPane.OK_OPTION) {
				newTetris();
				//NO就结束程序进程
			}else if(select == JOptionPane.NO_OPTION) {
				System.exit(0);
			}
			
		}
	}
	
	public void wall() {
		//画围墙
		for(int i = 0; i < 12; i++) {
			map[i][21] = 2;	//2就是在这个位置画围墙
		}
		
		for(int j = 0; j < 22; j++) {
			map[11][j] = 2;
			map[0][j] = 2;
		}
	}
	
	public void initMap() {
		//初始化地图
		for(int i = 0; i < 12; i++) {
			for(int j = 0; j < 22; j++) {
				map[i][j] = 0;	//0为地图的范围
			}
		}
	}
	
	public void rotate() {
		//方块旋转
		int tempRotateState = RotateState;	//RotateState1为不变的状态
		RotateState = (RotateState + 1)% 4;	//有规律的递增旋转 有4种状态
		if(legal(x, y, TetrisType, RotateState) == 1) {	//合法 继续旋转
		}
		
		if(legal(x, y, TetrisType, RotateState) == 0) {	//不合法 不旋转
			RotateState = tempRotateState;
		}
		repaint();
	}
	
	public void left() {
		//方块左移
		if(legal(x - 1, y, TetrisType, RotateState) == 1) {	//合法 左移
			x = x - 1;
		}
		repaint();
	}
	
	public void right() {
		//方块右移
		if(legal(x + 1, y, TetrisType, RotateState) == 1) {	//合法 右移
			x = x + 1;
		}
		repaint();
	}
	
	public void fall() {
		//方块下落
		if(legal(x, y + 1, TetrisType, RotateState) == 1) {
			y = y + 1;	
			removeRow();	//可以下落 消行
		}
		
		if(legal(x, y + 1, TetrisType, RotateState) == 0) {
			add(x, y, TetrisType, RotateState);	//无法下落，添加到地图
			newTetris();	//产生新方块
			removeRow();	
		}
		repaint();
	}
	
	public int legal(int x, int y, int TetrisType, int RotateState) {
		//判断是否合法
		for(int a = 0; a < 4; a++) {
			for(int b = 0; b < 4; b++) {
				if(((form[TetrisType][RotateState][a * 4 + b] == 1) && 
						(map[x  +b + 1][y + a] == 1)) ||
				((form[TetrisType][RotateState][a * 4 + b] == 1) && 
								(map[x +b + 1][y + a] == 2))){
					return 0;	//进到方块和边框中 不合法
				}
			}
		}
		return 1;	//合法
	}
	
	public void removeRow() {
		//消行方法
		int c = 0;	//c为行上面的一个小格子
		for(int b = 0; b < 22; b++) {
			for(int a = 0; a < 12;a++) {
				if(map[a][b] == 1) {	//碰到围墙格子了
					c = c + 1;	
					if(c == 10) {	//一行达到 消行
						score += 10;	//消行 分数加10
						for(int d = b; d > 0; d--) {
							for(int e = 0; e < 11; e++) {
								map[e][d] = map[e][d-1];	//消行的方块消失 上面的方块向下移动一行
							}
						}
					}
				}
			}
			c = 0;
		}
	}
	
	public int gameover(int x,int y) {
		//判断游戏结束方法
		if(legal(x, y, TetrisType, RotateState) == 0) {
			return 1;
		}
		return 0;
	}
	
	public void add(int x,int y,int TetrisType,int RotateState) {
		//把当前添加到地图中
		int j = 0;
		for(int a = 0; a < 4; a++) {
			for(int b = 0; b < 4; b++) {
				//初始位置从边框开始 所以x+1, y不用加1
				if(map[x + b + 1][y + a] == 0) {
					//方块不在地图内，保持类型和状态停止在底部
					map[x + b + 1][y + a] = form[TetrisType][RotateState][j];
				}
				j++;
			}
		}
	}
		
	public void paint(Graphics g) {
		//画方块
		super.paint(g);	//去除重影
		//画当前的方块
		for(j = 0; j < 16; j++) {	//方块矩阵
			if(form[TetrisType][RotateState][j] == 1) {
					//方块所在的x坐标和y坐标
				g.fillRect((j % 4 + x + 1)* 10, (j / 4 + y)* 10, 10, 10);
			}
		}
			//画已经固定的方块
		for(j = 0; j < 22; j++) {
			for(i = 0; i< 12; i++) {
				if(map[i][j] == 1) {	//位于矩形中的方块
					g.fillRect(i * 10, j * 10, 10, 10);
				}
				
				if(map[i][j] == 2) {	//画边框的方块
					g.drawRect(i * 10, j * 10, 10, 10);
				}
			}
		}
		g.drawString("score =" + score, 125, 10);	//画分数在图中的位置
	}
	
	
		public void keyPressed(KeyEvent e) {
			//键盘监听器
			switch(e.getKeyCode()) {
				//上下左右方向键控制方块
			case KeyEvent.VK_DOWN:
				fall();
				break;
			case KeyEvent.VK_UP:
				rotate();
				break;
			case KeyEvent.VK_RIGHT:
				right();
				break;
			case KeyEvent.VK_LEFT:
				left();
				break;
			}
		}
		
		@Override
		public void keyReleased(KeyEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void keyTyped(KeyEvent e) {
			// TODO Auto-generated method stub
			
		}

	class TimerListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			repaint();
			if(legal(x, y + 1, TetrisType, RotateState) == 1) {
				//合法
				y = y + 1;	//间隔一段时间下降1个身位
				removeRow();
			}
			
			if(legal(x, y + 1, TetrisType, RotateState) == 0) {
				//不合法，但方块已经放下
				if(flag == 1) {
					add(x, y, TetrisType, RotateState);	//直接添加到地图中
					//游戏结束 初始化
					removeRow();
					newTetris();
					flag = 0;	//方块未放下
				}
				flag = 1;
			}
		}
	}
}

public class Tetris extends JFrame{
	/**
	 * 
	 */
	public static final long serialVersionUID = 1L;

	public Tetris() {
		TetrisBlock tb=new TetrisBlock();
		addKeyListener(tb);	//添加键盘监听器
		add(tb);	//添加TetrisBlock到容器
	}
	
	public static void main(String[] args) {
		Tetris t = new Tetris();	
		JMenuBar menu = new JMenuBar();	//创建菜单
		t.setJMenuBar(menu);	//构造菜单
		
		t.setLocationRelativeTo(null);	//窗口位于屏幕中部	
		t.setSize(200,275);	//窗口的尺寸
		t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	//使用System.exit方法退出程序
		t.setVisible(true);	//显示或隐藏窗口
		t.setResizable(true);	//能由我调整窗口大小
	}
}